package com.gzc.just.play.last.war.common.handler;

import com.gzc.just.play.last.war.common.serializer.MessageDeserializer;
import com.gzc.just.play.last.war.common.thread.MessageHandler;
import com.gzc.just.play.last.war.common.thread.VirtualThreadMessageProcessor;
import io.netty.channel.ChannelHandlerContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 简单消息处理器适配器
 * 将SimpleMessageHandler适配为MessageHandler，以便在虚拟线程中处理
 */
public class SimpleMessageHandlerAdapter extends MessageHandler {
    private static final Logger logger = LoggerFactory.getLogger(SimpleMessageHandlerAdapter.class);
    
    private final SimpleMessageHandler simpleHandler;
    private final VirtualThreadMessageProcessor messageProcessor;
    
    /**
     * 构造函数
     * @param simpleHandler 原始的SimpleMessageHandler
     * @param messageProcessor 消息处理器
     */
    public SimpleMessageHandlerAdapter(SimpleMessageHandler simpleHandler, VirtualThreadMessageProcessor messageProcessor) {
        super(simpleHandler.getMessageId(), 
              createAdapterDeserializer(), 
              logger);
        this.simpleHandler = simpleHandler;
        this.messageProcessor = messageProcessor;
    }
    
    /**
     * 创建适配的反序列化器
     * 由于SimpleMessageHandler不直接提供反序列化器，我们需要创建一个适配器
     * @return 适配的反序列化器
     */
    private static MessageDeserializer createAdapterDeserializer() {
        return new MessageDeserializer() {
            @Override
            public Object deserialize(byte[] bytes) {
                // 由于SimpleMessageHandler不直接处理反序列化，
                // 我们在这里返回字节数组，由适配器处理
                return bytes;
            }
        };
    }
    
    /**
     * 处理消息
     * @param message 消息对象
     * @param context Netty通道上下文
     * @throws Exception 处理异常
     */
    @Override
    public void handleMessage(Object message, ChannelHandlerContext context) throws Exception {
        // 由于我们传递的是字节数组，需要在这里反序列化
        if (message instanceof byte[]) {
            byte[] messageBytes = (byte[]) message;
            
            // 获取消息类型
            Class<?> messageClass = getMessageClass(simpleHandler.getMessageId());
            if (messageClass == null) {
                logger.error("Unknown message ID: {}", simpleHandler.getMessageId());
                return;
            }
            
            // 使用Protobuf反序列化
            Object deserializedMessage = deserializeMessage(messageClass, messageBytes);
            if (deserializedMessage == null) {
                logger.error("Failed to deserialize message with ID: {}", simpleHandler.getMessageId());
                return;
            }
            
            // 调用原始处理器
            simpleHandler.handle(deserializedMessage, context);
        } else {
            // 不应该发生
            logger.error("Unexpected message type: {}", message != null ? message.getClass().getName() : "null");
        }
    }
    
    /**
     * 根据消息ID获取消息类
     * @param messageId 消息ID
     * @return 消息类，如果未知则返回null
     */
    private Class<?> getMessageClass(int messageId) {
        // 这里可以根据消息ID映射到具体的类
        // 由于protobuf类现在由protobuf-maven-plugin生成，我们需要使用反射来加载类
        try {
            switch (messageId) {
                case 40961: // GCToLS.AskLogin
                    return Class.forName("com.gzc.just.play.last.war.protobuf.gc.GCToLS$AskLogin");
                case 40962: // LSToGC.AskLoginRsp
                    return Class.forName("com.gzc.just.play.last.war.protobuf.ls.LSToGC$AskLoginRsp");
                default:
                    logger.warn("Unknown message ID: {}", messageId);
                    return null;
            }
        } catch (ClassNotFoundException e) {
            logger.error("Failed to find message class for ID: {}", messageId, e);
            return null;
        }
    }
    
    /**
     * 反序列化消息
     * @param messageClass 消息类
     * @param messageBytes 消息字节数组
     * @return 反序列化后的消息对象
     */
    private Object deserializeMessage(Class<?> messageClass, byte[] messageBytes) {
        try {
            // 使用反射调用parseFrom方法
            return messageClass.getMethod("parseFrom", byte[].class).invoke(null, messageBytes);
        } catch (Exception e) {
            logger.error("Failed to deserialize message", e);
            return null;
        }
    }
}